home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / glibmm-2.4 / proc / pm / Output.pm < prev    next >
Text File  |  2006-04-20  |  23KB  |  818 lines

  1. # Gtkmmproc Output module
  2. #
  3. # Copyright 2001 Free Software Foundation
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18. #
  19. package Output;
  20. use strict;
  21. BEGIN { @Namespace::ISA=qw(main); }
  22.  
  23. # $objOutputter new()
  24. sub new
  25. {
  26.   my ($m4path, $macrodirs) = @_;
  27.   my $self = {};
  28.   bless $self;
  29.  
  30.   $$self{out} = [];
  31.  
  32.   $$self{source} = "";
  33.   $$self{tmpdir} = "/tmp";
  34.   $$self{destdir} = "";
  35.   $$self{objDefsParser} = undef; # It will be set in set_defsparser()
  36.  
  37.   $$self{m4path} = $m4path;
  38.   $$self{m4args} = "-I";
  39.   $$self{m4args} .= join(" -I", @$macrodirs);
  40.  
  41.   return $self;
  42. }
  43.  
  44. sub set_defsparser($$)
  45. {
  46.   my ($self, $objDefsParser) = @_;
  47.  
  48.   $$self{objDefsParser} = $objDefsParser; #Remember it so that we can use it in our output methods.
  49. }
  50.  
  51. sub m4args_append($$)
  52. {
  53.   my ($self, $str) = @_;
  54.   $$self{m4args} .= $str;
  55. }
  56.  
  57. sub append($$)
  58. {
  59.   my ($self, $str) = @_;
  60.  
  61.   push(@{$$self{out}}, $str);
  62. }
  63.  
  64. # void output_wrap_failed($cname, $error)
  65. # Puts a comment in the header about the error during code-generation.
  66. sub output_wrap_failed($$$)
  67. {
  68.   my ($self, $cname, $error) = @_;
  69.  
  70.   my $str = sprintf("//gtkmmproc error: %s : %s", $cname, $error);
  71.   print STDERR "Output.pm: $cname : $error\n";
  72.   $self->append($str);
  73. }
  74.  
  75. sub error
  76. {
  77.   my $format=shift @_;
  78.   printf STDERR "Output.pm: $format",@_;
  79. }
  80.  
  81. ### Convert _WRAP to a virtual 
  82. # _VFUNC_H(signame,rettype,`<cppargs>')
  83. # _VFUNC_PH(gtkname,crettype,cargs and names)
  84. # void output_wrap_vfunc_h($filename, $line_num, $objCppfunc, $objCDefsFunc)
  85. sub output_wrap_vfunc_h($$$$$)
  86. {
  87.   my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc) = @_;
  88.  
  89. #TODO: We can probably remove _VFUNC_H from the .m4 file
  90. #  my $str = sprintf("_VFUNC_H(%s,%s,\`%s\',%s)dnl\n",
  91. #    $$objCppfunc{name},
  92. #    $$objCppfunc{rettype},
  93. #    $objCppfunc->args_types_and_names(),
  94. #    $objCppfunc->get_is_const()
  95. #   );
  96. #  $self->append($str);
  97.  
  98.   my $cppVfuncDecl = "virtual " . $$objCppfunc{rettype} . " " . $$objCppfunc{name} . "(" . $objCppfunc->args_types_and_names() . ")";
  99.   if($objCppfunc->get_is_const())
  100.   {
  101.     $cppVfuncDecl .= " const";
  102.   }
  103.  
  104.   $self->append("  $cppVfuncDecl;");
  105.  
  106.   #The default callback, which will call *_vfunc, which will then call the base default callback.
  107.   #Declares the callback in the private *Class class and sets it in the class_init function.
  108.  
  109.   my $str = sprintf("_VFUNC_PH(%s,%s,\`%s\')dnl\n",
  110.     $$objCDefsFunc{name},
  111.     $$objCDefsFunc{rettype},
  112.     $objCDefsFunc->args_types_and_names(),
  113.    );
  114.   $self->append($str);
  115. }
  116.  
  117. # _VFUNC_CC(signame,gtkname,rettype,crettype,`<cppargs>',`<cargs>')
  118. sub output_wrap_vfunc_cc($$$$$$)
  119. {
  120.   my ($self, $filename, $line_num, $objCppfunc, $objDefsSignal) = @_;
  121.  
  122.   my $cname = $$objDefsSignal{name};
  123.  
  124.   # e.g. Gtk::Button::draw_indicator:
  125.  
  126.   #Use a different macro for Interfaces, to generate an extra convenience method.
  127.  
  128.   my $refreturn = "";
  129.   $refreturn = "refreturn" if($$objCppfunc{rettype_needs_ref});
  130.  
  131.   my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s)dnl\n",
  132.     $$objCppfunc{name},
  133.     $cname,
  134.     $$objCppfunc{rettype},
  135.     $$objDefsSignal{rettype},
  136.     $objCppfunc->args_types_and_names(),
  137.     convert_args_cpp_to_c($objCppfunc, $objDefsSignal, 0, $line_num), #$objCppfunc->args_names_only(),
  138.     $objCppfunc->get_is_const(),
  139.     $refreturn);
  140.  
  141.   $self->append($str);
  142.  
  143.   # e.g. Gtk::ButtonClass::draw_indicator():
  144.  
  145.   my $refreturn_ctype = "";
  146.   $refreturn_ctype = "refreturn_ctype" if($$objDefsSignal{rettype_needs_ref});
  147.  
  148.   my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s)dnl\n",
  149.     $$objCppfunc{name},
  150.     $cname,
  151.     $$objCppfunc{rettype},
  152.     $$objDefsSignal{rettype},
  153.     $objDefsSignal->args_types_and_names(),
  154.     $objDefsSignal->args_names_only(),
  155.     convert_args_c_to_cpp($objDefsSignal, $objCppfunc, $line_num),
  156.     ${$objDefsSignal->get_param_names()}[0],
  157.     $refreturn_ctype);
  158.  
  159.   $self->append($str);
  160. }
  161.  
  162. ### Convert _WRAP to a virtual
  163. # _SIGNAL_H(signame,rettype,`<cppargs>')
  164. # _SIGNAL_PH(gtkname,crettype,cargs and names)
  165. # void output_wrap_default_signal_handler_h($filename, $line_num, $objCppfunc, $objCDefsFunc, @args)
  166. sub output_wrap_default_signal_handler_h($$$$$$)
  167. {
  168.   my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $bImplement) = @_;
  169.  
  170.   my $str = sprintf("_SIGNAL_H(%s,%s,\`%s\')dnl\n",
  171.     $$objCppfunc{name},
  172.     $$objCppfunc{rettype},
  173.     $objCppfunc->args_types_and_names()
  174.    );
  175.   $self->append($str);
  176.  
  177.  
  178.   #The default callback, which will call *_impl, which will then call the base default callback.
  179.   #Declares the callback in the private *Class class and sets it in the class_init function.
  180.  
  181.   $str = sprintf("_SIGNAL_PH(%s,%s,\`%s\')dnl\n",
  182.     $$objCDefsFunc{name},
  183.     $$objCDefsFunc{rettype},
  184.     $objCDefsFunc->args_types_and_names()
  185.    );
  186.   $self->append($str);
  187. }
  188.  
  189. # _SIGNAL_CC(signame, gtkname, rettype, crettype,`<cppargs>',`<cargs>')
  190. sub output_wrap_default_signal_handler_cc($$$$$$$$)
  191. {
  192.   my ($self, $filename, $line_num, $objCppfunc, $objDefsSignal, $bImplement, $bCustomCCallback, $bRefreturn) = @_;
  193.   my $cname = $$objDefsSignal{name};
  194.   # $cname = $1 if ($args[3] =~ /"(.*)"/); #TODO: What's this about?
  195.  
  196.   # e.g. Gtk::Button::on_clicked:
  197.   if($bImplement eq 1)
  198.   {
  199.     my $refreturn = "";
  200.     $refreturn = "refreturn" if($bRefreturn eq 1);
  201.   
  202.     my $str = sprintf("_SIGNAL_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s, %s)dnl\n",
  203.       $$objCppfunc{name},
  204.       $cname,
  205.       $$objCppfunc{rettype},
  206.       $$objDefsSignal{rettype},
  207.       $objCppfunc->args_types_and_names(),
  208.       convert_args_cpp_to_c($objCppfunc, $objDefsSignal, 0, $line_num), #$objCppfunc->args_names_only(),
  209.       $$objCppfunc{const},
  210.       $refreturn);
  211.     $self->append($str);
  212.   }
  213.  
  214.  
  215.   # e.g. Gtk::ButtonClass::on_clicked():
  216.  
  217.   #Callbacks always take the object instance as the first argument:
  218. #  my $arglist_names = "object";
  219. #  my $arglist_names_extra = $objDefsSignal->args_names_only();
  220. #  if ($arglist_names_extra)
  221. #  {
  222. #    $arglist_names .= ", ";
  223. #    $arglist_names .= $arglist_names_extra;
  224. #  }
  225.  
  226.   if($bCustomCCallback ne 1)
  227.   {
  228.     my $str = sprintf("_SIGNAL_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s)dnl\n",
  229.       $$objCppfunc{name},
  230.       $cname,
  231.       $$objCppfunc{rettype},
  232.       $$objDefsSignal{rettype},
  233.       $objDefsSignal->args_types_and_names(),
  234.       $objDefsSignal->args_names_only(),
  235.       convert_args_c_to_cpp($objDefsSignal, $objCppfunc, $line_num),
  236.       ${$objDefsSignal->get_param_names()}[0]);
  237.     $self->append($str);
  238.   }
  239. }
  240.  
  241. ### Convert _WRAP to a method
  242. #  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
  243. #  void output_wrap_meth($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl, $documentation)
  244. sub output_wrap_meth($$$$$$)
  245. {
  246.   my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl, $documentation) = @_;
  247.   my $objDefsParser = $$self{objDefsParser};
  248.  
  249.   # Doxygen documentation before the method declaration:
  250.   $self->output_wrap_meth_docs_only($filename, $line_num, $documentation);
  251.  
  252.   #Declaration:
  253.   $self->append("  ${cppMethodDecl};");
  254.  
  255.   my $refneeded = "";
  256.   if($$objCDefsFunc{rettype_needs_ref})
  257.   {
  258.     $refneeded = "refreturn"
  259.   }
  260.   my $errthrow = "";
  261.   if($$objCDefsFunc{throw_any_errors})
  262.   {
  263.     $errthrow = "errthrow"
  264.   }
  265.  
  266.   #Implementation:
  267.   my $str;
  268.   if ($$objCppfunc{static}) {
  269.     $str = sprintf("_STATIC_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s)dnl\n",
  270.       $$objCppfunc{name},
  271.       $$objCDefsFunc{c_name},
  272.       $$objCppfunc{rettype},
  273.       $objCDefsFunc->get_return_type_for_methods(),
  274.       $objCppfunc->args_types_and_names(),
  275.       convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 1, $line_num, $errthrow), #1 means it's static, so it has 'object'.
  276.       $refneeded,
  277.       $errthrow);
  278.   } else {
  279.     $str = sprintf("_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
  280.       $$objCppfunc{name},
  281.       $$objCDefsFunc{c_name},
  282.       $$objCppfunc{rettype},
  283.       $objCDefsFunc->get_return_type_for_methods(),
  284.       $objCppfunc->args_types_and_names(),
  285.       convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 0, $line_num, $errthrow),
  286.       $$objCppfunc{const},
  287.       $refneeded,
  288.       $errthrow);
  289.   }
  290.  
  291.  
  292.   $self->append($str);
  293. }
  294.  
  295. ### Convert _WRAP to a method
  296. #  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
  297. #  void output_wrap_meth($filename, $line_num, $documentation)
  298. sub output_wrap_meth_docs_only($$$$)
  299. {
  300.   my ($self, $filename, $line_num, $documentation) = @_;
  301.   my $objDefsParser = $$self{objDefsParser};
  302.  
  303.   # Doxygen documentation before the method declaration:
  304.   $self->append("\n${documentation}");
  305. }
  306.  
  307. ### Convert _WRAP_CTOR to a ctor
  308. #  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
  309. #  void output_wrap_ctor($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl)
  310. sub output_wrap_ctor($$$$$)
  311. {
  312.   my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl) = @_;
  313.   my $objDefsParser = $$self{objDefsParser};
  314.  
  315.   #Ctor Declaration:
  316.   #TODO: Add explicit.
  317.   $self->append("explicit " . $cppMethodDecl . ";");
  318.  
  319.   #Implementation:
  320.   my $str = sprintf("_CTOR_IMPL(%s,%s,\`%s\',\`%s\')dnl\n",
  321.     $$objCppfunc{name},
  322.     $$objCDefsFunc{c_name},
  323.     $objCppfunc->args_types_and_names(),
  324.     get_ctor_properties($objCppfunc, $objCDefsFunc, $line_num)
  325.   );
  326.  
  327.   $self->append($str);
  328. }
  329.  
  330. sub output_wrap_create($$$)
  331. {
  332.   my ($self, $args_type_and_name_with_default_values, $objWrapParser) = @_;
  333.  
  334.   #Re-use Function in a very hacky way, to separate the argument types_and_names.
  335.   my $fake_decl = "void fake_func(" . $args_type_and_name_with_default_values . ")";
  336.  
  337.   my $objFunction = &Function::new($fake_decl, $objWrapParser);
  338.   my $args_names_only = $objFunction->args_names_only();
  339.   my $args_type_and_name_hpp = $objFunction->args_types_and_names_with_default_values();
  340.   my $args_type_and_name_cpp = $objFunction->args_types_and_names();
  341.  
  342.   my $str = sprintf("_CREATE_METHOD(\`%s\',\`%s\',\`%s\')dnl\n",
  343.               $args_type_and_name_hpp, , $args_type_and_name_cpp, $args_names_only);
  344.  
  345.   $self->append($str)
  346. }
  347.  
  348. # void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback)
  349. # custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead.
  350. sub output_wrap_sig_decl($$$$$$$)
  351. {
  352.   my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback) = @_;
  353.  
  354. # _SIGNAL_PROXY(c_signal_name, c_return_type, `<c_arg_types_and_names>',
  355. #               cpp_signal_name, cpp_return_type, `<cpp_arg_types>',`<c_args_to_cpp>',
  356. #               refdoc_comment)
  357.  
  358.   my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\')dnl\n",
  359.     $signal_name,
  360.     $$objCSignal{rettype},
  361.     $objCSignal->args_types_and_names_without_object(),
  362.     $$objCppfunc{name},
  363.     $$objCppfunc{rettype},
  364.     $objCppfunc->args_types_only(),
  365.     convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num),
  366.     $bCustomCCallback, #When this is true, it will not write the *_callback implementation for you.
  367.     $objCppfunc->get_refdoc_comment()
  368.   );
  369.  
  370.   $self->append($str);
  371. }
  372.  
  373. # void output_wrap_enum($filename, $line_num, $cpp_type, $c_type, $comment, @flags)
  374. sub output_wrap_enum($$$$$$$)
  375. {
  376.   my ($self, $filename, $line_num, $cpp_type, $c_type, $comment, @flags) = @_;
  377.  
  378.   my $objEnum = GtkDefs::lookup_enum($c_type);
  379.   if(!$objEnum)
  380.   {
  381.     $self->output_wrap_failed($c_type, "enum defs lookup failed.");
  382.     return;
  383.   }
  384.  
  385.   $objEnum->beautify_values();
  386.  
  387.   my $no_gtype = "";
  388.   my $elements = $objEnum->build_element_list(\@flags, \$no_gtype, "  ");
  389.  
  390.   if(!$elements)
  391.   {
  392.     $self->output_wrap_failed($c_type, "unknown _WRAP_ENUM() flag");
  393.     return;
  394.   }
  395.  
  396.   my $value_suffix = "Enum";
  397.   $value_suffix = "Flags" if($$objEnum{flags});
  398.  
  399.   my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\')dnl\n",
  400.     $cpp_type,
  401.     $c_type,
  402.     $value_suffix,
  403.     $elements,
  404.     $no_gtype,
  405.     $comment
  406.   );
  407.  
  408.   $self->append($str);
  409. }
  410.  
  411. # void output_wrap_gerror($filename, $line_num, $cpp_type, $c_enum, $domain, @flags)
  412. sub output_wrap_gerror($$$$$$$)
  413. {
  414.   my ($self, $filename, $line_num, $cpp_type, $c_enum, $domain, @flags) = @_;
  415.  
  416.   my $objDefsParser = $$self{objDefsParser};
  417.  
  418.   my $objEnum = GtkDefs::lookup_enum($c_enum);
  419.   if(!$objEnum)
  420.   {
  421.     $self->output_wrap_failed($c_enum, "enum defs lookup failed.");
  422.     return;
  423.   }
  424.  
  425.   # Shouldn't happen, and if it does, I'd like to know that.
  426.   warn if($$objEnum{flags});
  427.  
  428.   $objEnum->beautify_values();
  429.  
  430.   # cut off the module prefix, e.g. GDK_
  431.   my $prefix = $domain;
  432.   $prefix =~ s/^[^_]+_//;
  433.  
  434.   # Chop off the domain prefix, because we put the enum into the class.
  435.   unshift(@flags, "s#^${prefix}_##");
  436.  
  437.   my $no_gtype = "";
  438.   my $elements = $objEnum->build_element_list(\@flags, \$no_gtype, "    ");
  439.  
  440.   my $str = sprintf("_GERROR(%s,%s,%s,\`%s\',%s)dnl\n",
  441.     $cpp_type,
  442.     $c_enum,
  443.     $domain,
  444.     $elements,
  445.     $no_gtype
  446.   );
  447.  
  448.   $self->append($str);
  449. }
  450.  
  451. # _PROPERTY_PROXY(name, cpp_type)
  452. # void output_wrap_property($filename, $line_num, $name, $cpp_type)
  453. sub output_wrap_property($$$$$$)
  454. {
  455.   my ($self, $filename, $line_num, $name, $cpp_type, $c_class) = @_;
  456.  
  457.   my $objDefsParser = $$self{objDefsParser};
  458.  
  459.   my $objProperty = GtkDefs::lookup_property($c_class, $name);
  460.   if($objProperty eq 0) #If the lookup failed:
  461.   {
  462.     $self->output_wrap_failed($name, "property defs lookup failed.");
  463.   }
  464.   else
  465.   {
  466.     # We use a suffix to specify a particular Glib::PropertyProxy* class.
  467.     my $proxy_suffix = "";
  468.  
  469.     # Read/Write:
  470.     if($objProperty->get_construct_only() eq 1)
  471.     {
  472.       # construct-only functions can be read, but not written.
  473.       $proxy_suffix = "_ReadOnly";
  474.     }
  475.     elsif($objProperty->get_readable() ne 1)
  476.     {
  477.       $proxy_suffix = "_WriteOnly";
  478.     }
  479.     elsif($objProperty->get_writable() ne 1)
  480.     {
  481.        $proxy_suffix = "_ReadOnly";
  482.     }
  483.  
  484.     # Convert - to _ so we can use it in C++ method and variable names:
  485.     my $name_underscored = $name;
  486.     $name_underscored =~ s/-/_/g;
  487.  
  488.     my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s)dnl\n",
  489.       $name,
  490.       $name_underscored,
  491.       $cpp_type,
  492.       $proxy_suffix,
  493.       $objProperty->get_docs()
  494.     );
  495.     $self->append($str);
  496.     $self->append("\n");
  497.  
  498.     # If the property is not already read-only, and the property can be read, then add a second const accessor for a read-only propertyproxy:
  499.     if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
  500.     {
  501.       my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s)dnl\n",
  502.         $name,
  503.         $name_underscored,
  504.         $cpp_type,
  505.         "_ReadOnly",
  506.         $objProperty->get_docs()
  507.       );
  508.       $self->append($str);
  509.     }
  510.  
  511.     
  512.   }
  513. }
  514.  
  515. # vpod output_temp_g1($filename, $section) e.g. output_temp_g1(button, gtk)
  516. sub output_temp_g1($$)
  517. {
  518.   my ($self, $section) = @_;
  519.  
  520.   # Write out *.g1 temporary file
  521.   open(FILE, '>', "$$self{tmpdir}/gtkmmproc_$$.g1");  # $$ is the Process ID
  522.  
  523.   print FILE "include(base.m4)dnl\n";
  524.  
  525.   my $module = $section;
  526.   my $module_canonical = Util::string_canonical($module); #In case there is a / character in the module.
  527.   print FILE "_START($$self{source},$module,$module_canonical)dnl\n";
  528.   print FILE join("", @{$$self{out}});
  529.   print FILE "_END()\n";
  530.   close(FILE);
  531. }
  532.  
  533. sub make_g2_from_g1($)
  534. {
  535.   my ($self) = @_;
  536.  
  537.   # Execute m4 to get *.g2 file:
  538.   system("$$self{m4path} $$self{m4args} '$$self{tmpdir}/gtkmmproc_$$.g1' > '$$self{tmpdir}/gtkmmproc_$$.g2'");
  539.   return ($? >> 8);
  540. }
  541.  
  542. # void write_sections_to_files()
  543. # This is where we snip the /tmp/gtkmmproc*.g2 file into sections (,h, .cc, _private.h)
  544. sub write_sections_to_files()
  545. {
  546.   my ($self) = @_;
  547.  
  548.   my $fname_h  = "$$self{destdir}/$$self{source}.h";
  549.   my $fname_ph = "$$self{destdir}/private/$$self{source}_p.h";
  550.   my $fname_cc = "$$self{destdir}/$$self{source}.cc";
  551.  
  552.   open(INPUT, '<', "$$self{tmpdir}/gtkmmproc_$$.g2"); # $$ is the process ID.
  553.  
  554.   # open tempory file for each section
  555.   open(OUTPUT_H,  '>', "$fname_h.tmp");
  556.   open(OUTPUT_PH, '>', "$fname_ph.tmp");
  557.   open(OUTPUT_CC, '>', "$fname_cc.tmp");
  558.  
  559.   my $oldfh = select(OUTPUT_H);
  560.   my $blank = 0;
  561.  
  562.   while(<INPUT>)
  563.   {
  564.     # section switching
  565.     if(/^#S 0/) { select(OUTPUT_H);  next; }
  566.     if(/^#S 1/) { select(OUTPUT_PH); next; }
  567.     if(/^#S 2/) { select(OUTPUT_CC); next; }
  568.  
  569.     # get rid of bogus blank lines
  570.     if(/^\s*$/) { ++$blank; } else { $blank = 0; }
  571.     next if($blank > 2);
  572.  
  573.     print $_;
  574.   }
  575.  
  576.   select($oldfh);
  577.   close(INPUT);
  578.   close(OUTPUT_H);
  579.   close(OUTPUT_PH);
  580.   close(OUTPUT_CC);
  581.  
  582.   foreach($fname_h, $fname_ph, $fname_cc)
  583.   {
  584.     # overwrite the source file only if it has actually changed
  585.     system("cmp -s '$_.tmp' '$_' || cp '$_.tmp' '$_' ; rm -f '$_.tmp'");
  586.   }
  587. }
  588.  
  589.  
  590. sub remove_temp_files($)
  591. {
  592.   my ($self) = @_;
  593.  
  594.   system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g1\"");
  595.   system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g2\"");
  596. }
  597.  
  598.  
  599.  
  600. # procedure for generating CONVERT macros
  601. # $string convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, $static, $wrap_line_number,$automatic_error)
  602. sub convert_args_cpp_to_c($$$$;$)
  603. {
  604.   my ($objCppfunc, $objCDefsFunc, $static, $wrap_line_number, $automatic_error) = @_;
  605.  
  606.   $automatic_error = "" unless defined $automatic_error;
  607.  
  608.   my $cpp_param_names = $$objCppfunc{param_names};
  609.   my $cpp_param_types = $$objCppfunc{param_types};
  610.   my $c_param_types = $$objCDefsFunc{param_types};
  611.  
  612.   my @result;
  613.  
  614.   my $num_c_args_expected = scalar(@{$c_param_types});
  615.   if( !($static) ) { $num_c_args_expected--; } #The cpp method will need an Object* paramater at the start.
  616.  
  617.   my $num_cpp_args = scalar(@{$cpp_param_types});
  618.  
  619.   # add implicit last error parameter;
  620.   if ( $automatic_error ne "" &&
  621.        $num_cpp_args == ($num_c_args_expected - 1) &&
  622.        ${$c_param_types}[-1] eq "GError**" )
  623.   {
  624.     $num_cpp_args++;
  625.     $cpp_param_names = [@{$cpp_param_names},"error"];
  626.     $cpp_param_types = [@{$cpp_param_types},"GError*&"];
  627.   }
  628.  
  629.   if ( $num_cpp_args != $num_c_args_expected )
  630.   {
  631.     Output::error( "convert_args_cpp_to_c(): Incorrect number of arguments. (%d != %d)\n",
  632.              $num_cpp_args,
  633.              $num_c_args_expected );
  634.     $objCppfunc->dump();
  635.     $objCDefsFunc->dump();
  636.  
  637.     return "";
  638.   }
  639.  
  640.  
  641.   # Loop through the cpp parameters:
  642.  my $i;
  643.  my $cpp_param_max = $num_cpp_args;
  644.  # if( !($static) ) { $cpp_param_max++; }
  645.  
  646.  for ($i = 0; $i < $cpp_param_max; $i++)
  647.  {
  648.    #index of C parameter:
  649.    my $iCParam = $i;
  650.    if( !($static) ) { $iCParam++; }
  651.  
  652.    my $cppParamType = $$cpp_param_types[$i];
  653.    $cppParamType =~ s/ &/&/g; #Remove space between type and &
  654.    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
  655.  
  656.    my $cppParamName = $$cpp_param_names[$i];
  657.    my $cParamType = $$c_param_types[$iCParam];
  658.  
  659.    if ($cppParamType ne $cParamType) #If a type conversion is needed.
  660.    {
  661.  
  662.  
  663.      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
  664.                   $cppParamType,
  665.                   $cParamType,
  666.                   $cppParamName,
  667.                   $wrap_line_number) );
  668.     }
  669.     else
  670.     {
  671.       push(@result, $cppParamName);
  672.     }
  673.   }
  674.  
  675.   return join(", ", @result);
  676. }
  677.  
  678. # procedure for generating CONVERT macros
  679. # Ignores the first C 'self' argument.
  680. # $string convert_args_c_to_cpp($objCDefsFunc, $objCppFunc, $wrap_line_number)
  681. sub convert_args_c_to_cpp($$$)
  682. {
  683.   my ($objCDefsFunc, $objCppfunc, $wrap_line_number) = @_;
  684.  
  685.   my $cpp_param_types = $$objCppfunc{param_types};
  686.   my $c_param_types = $$objCDefsFunc{param_types};
  687.   my $c_param_names = $$objCDefsFunc{param_names};
  688.  
  689.   my @result;
  690.  
  691.   my $num_c_args = scalar(@{$c_param_types});
  692.  
  693.   my $num_cpp_args = scalar(@{$cpp_param_types});
  694.  
  695.   if ( ($num_cpp_args + 1) !=  $num_c_args )
  696.   {
  697.     Output::error( "convert_args_c_to_cpp(): Incorrect number of arguments. (%d != %d)\n",
  698.              $num_cpp_args + 1,
  699.              $num_c_args);
  700.     $objCppfunc->dump();
  701.     $objCDefsFunc->dump();
  702.  
  703.     return "";
  704.   }
  705.  
  706.  
  707.   # Loop through the c parameters:
  708.  my $i;
  709.  my $c_param_max = $num_c_args;
  710.  
  711.  for ($i = 1; $i < $c_param_max; $i++)
  712.  {
  713.    #index of C parameter:
  714.    my $iCppParam = $i - 1;
  715.  
  716.    my $cppParamType = $$cpp_param_types[$iCppParam];
  717.    $cppParamType =~ s/ &/&/g; #Remove space between type and &.
  718.    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
  719.  
  720.    my $cParamName = $$c_param_names[$i];
  721.    my $cParamType = $$c_param_types[$i];
  722.  
  723.    if ($cParamType ne $cppParamType) #If a type conversion is needed.
  724.    {
  725.      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)\n",
  726.                   $cParamType,
  727.                   $cppParamType,
  728.                   $cParamName,
  729.                   $wrap_line_number) );
  730.     }
  731.     else
  732.     {
  733.       push(@result, $cParamName);
  734.     }
  735.   }
  736.  
  737.   return join(", ",@result);
  738. }
  739.  
  740.  
  741. # generates the XXX in g_object_new(get_type(), XXX): A list of property names and values.
  742. # Uses the cpp arg name as the property name.
  743. # $string get_ctor_properties($objCppfunc, $objCDefsFunc, $wrap_line_number)
  744. sub get_ctor_properties($$$$)
  745. {
  746.  my ($objCppfunc, $objCDefsFunc, $wrap_line_number) = @_;
  747.  
  748.   my $cpp_param_names = $$objCppfunc{param_names};
  749.   my $cpp_param_types = $$objCppfunc{param_types};
  750.   my $c_param_types = $$objCDefsFunc{param_types};
  751.  
  752.   my @result;
  753.  
  754.   my $num_args = scalar(@{$c_param_types});
  755.  
  756.   my $num_cpp_args = scalar(@{$cpp_param_types});
  757.   if ( $num_cpp_args != $num_args )
  758.   {
  759.     Output::error("get_ctor_properties(): Incorrect number of arguments. (%d != %d)\n",
  760.              $num_cpp_args,
  761.              $num_args );
  762.     return "";
  763.   }
  764.  
  765.  
  766.   # Loop through the cpp parameters:
  767.  my $i = 0;
  768.  
  769.  for ($i = 0; $i < $num_args; $i++)
  770.  {
  771.    my $cppParamType = $$cpp_param_types[$i];
  772.    $cppParamType =~ s/ &/&/g; #Remove space between type and &
  773.    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
  774.  
  775.    my $cppParamName = $$cpp_param_names[$i];
  776.    my $cParamType = $$c_param_types[$i];
  777.  
  778.    # Property name:
  779.    push(@result, "\"" . $cppParamName . "\"");
  780.  
  781.    # C property value:
  782.    if ($cppParamType ne $cParamType) #If a type conversion is needed.
  783.    {
  784.      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
  785.                   $cppParamType,
  786.                   $cParamType,
  787.                   $cppParamName,
  788.                   $wrap_line_number) );
  789.     }
  790.     else
  791.     {
  792.       push(@result, $cppParamName);
  793.     }
  794.   }
  795.  
  796.   return join(", ", @result);
  797. }
  798.  
  799. ### Convert _WRAP to a corba method
  800. # _CORBA_METHOD(retype, method_name,args, arg_names_only) - implemented in libbonobomm.
  801. #  void output_wrap_corba_method($filename, $line_num, $objCppFunc)
  802. sub output_wrap_corba_method($$$$)
  803. {
  804.   my ($self, $filename, $line_num, $objCppfunc) = @_;
  805.  
  806.   my $str = sprintf("_CORBA_METHOD(%s,%s,\`%s\',\`%s\')dnl\n",
  807.       $$objCppfunc{rettype},
  808.       $$objCppfunc{name},
  809.       $objCppfunc->args_types_and_names(),
  810.       $objCppfunc->args_names_only()
  811.    );
  812.  
  813.   $self->append($str);
  814. }
  815.  
  816.  
  817. 1; # indicate proper module load.
  818.